import axios from 'axios'
import { Loading, Message } from 'element-ui'
import { getToken } from '@/utils/auth'
import { blobValidate } from '@/utils/ruoyi'

const baseURL = process.env.VUE_APP_BASE_API
let downloadLoadingInstance

/**
 * 通用下载方法
 * @param {String} url - 下载地址
 * @param {Object} params - 请求参数
 * @param {String} filename - 文件名
 * @param {String} method - 请求方法，支持 'get' 或 'post'
 */
export function download(url, params, filename, method = 'get') {
  downloadLoadingInstance = Loading.service({
    text: '正在下载数据，请稍候',
    spinner: 'el-icon-loading',
    background: 'rgba(0, 0, 0, 0.7)'
  })

  // 拼接完整的 URL
  if (url.indexOf('http') !== 0) {
    url = baseURL + url
  }

  return axios({
    method: method,
    url: url,
    params: method === 'get' ? params : null,
    data: method === 'post' ? params : null,
    responseType: 'blob',
    headers: { 'Authorization': 'Bearer ' + getToken() }
  }).then(res => {
    const isBlob = blobValidate(res.data)
    if (isBlob) {
      const blob = new Blob([res.data], { type: res.data.type })
      let downloadFilename = filename
      // 优先使用服务端返回的文件名
      if (res.headers && res.headers['content-disposition']) {
        const contentDisposition = res.headers['content-disposition']
        const filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/
        const matches = filenameRegex.exec(contentDisposition)
        if (matches != null && matches[1]) {
          downloadFilename = matches[1].replace(/['"]/g, '')
        }
      }
      saveAs(blob, downloadFilename)
    } else {
      printErrMsg(res.data)
    }
    downloadLoadingInstance.close()
  }).catch(error => {
    console.error(error)
    Message.error('下载文件出现错误，请联系管理员！')
    downloadLoadingInstance.close()
  })
}

/**
 * 解析并打印错误消息
 * @param {Blob} data
 */
async function printErrMsg(data) {
  const resText = await data.text()
  let rspObj = null
  try {
    rspObj = JSON.parse(resText)
  } catch (error) {
    Message.error('下载文件解析异常')
    return
  }
  const errorCode = {
    '401': '认证失败，无法访问系统资源',
    '403': '当前操作没有权限',
    '404': '访问资源不存在',
    'default': '系统未知错误，请反馈给管理员'
  }
  const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
  Message.error(errMsg)
}

/**
 * 保存文件
 */
function saveAs(blob, filename) {
  if (window.navigator.msSaveOrOpenBlob) {
    navigator.msSaveBlob(blob, filename)
  } else {
    const link = document.createElement('a')
    const body = document.querySelector('body')

    link.href = window.URL.createObjectURL(blob)
    link.download = filename
    link.style.display = 'none'

    body.appendChild(link)
    link.click()
    body.removeChild(link)
    window.URL.revokeObjectURL(link.href)
  }
}

/**
 * 下载模板文件
 * @param {String} url - 模板下载地址（相对路径，会自动拼接baseURL）
 * @param {String} filename - 可选的文件名，如果不传则由浏览器自动处理
 */
export function downloadTemplate(url, filename = null) {
  const baseURL = process.env.VUE_APP_BASE_API
  const fullUrl = url.startsWith('http') ? url : baseURL + url
  const token = getToken()

  if (filename) {
    // 如果指定了文件名，使用fetch方式下载并携带token
    fetch(fullUrl, {
      method: 'GET',
      headers: {
        'Authorization': 'Bearer ' + token,
        'Content-Type': 'application/json'
      }
    })
      .then(response => {
        if (!response.ok) {
          throw new Error(`HTTP error! status: ${response.status}`)
        }
        return response.blob()
      })
      .then(blob => {
        saveAs(blob, filename)
      })
      .catch(error => {
        console.error('下载模板失败:', error)
        Message.error('下载模板失败，请检查网络连接或联系管理员')
      })
  } else {
    // 没有指定文件名，使用axios方式下载并携带token
    axios({
      method: 'get',
      url: fullUrl,
      responseType: 'blob',
      headers: { 'Authorization': 'Bearer ' + token }
    }).then(res => {
      const isBlob = blobValidate(res.data)
      if (isBlob) {
        const blob = new Blob([res.data], { type: res.data.type })
        let downloadFilename = 'template.xlsx'
        // 优先使用服务端返回的文件名
        if (res.headers && res.headers['content-disposition']) {
          const contentDisposition = res.headers['content-disposition']
          const filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/
          const matches = filenameRegex.exec(contentDisposition)
          if (matches != null && matches[1]) {
            downloadFilename = matches[1].replace(/['"]/g, '')
          }
        }
        saveAs(blob, downloadFilename)
      } else {
        printErrMsg(res.data)
      }
    }).catch(error => {
      console.error('下载模板失败:', error)
      Message.error('下载模板失败，请检查网络连接或联系管理员')
    })
  }
}

/**
 * 下载模板文件（POST请求）
 * @param {String} url - 模板下载地址（相对路径，会自动拼接baseURL）
 * @param {String} filename - 文件名
 * @param {Object} data - 可选的POST请求数据
 */
export function downloadTemplatePost(url, filename, data = {}) {
  const baseURL = process.env.VUE_APP_BASE_API
  const fullUrl = url.startsWith('http') ? url : baseURL + url
  const token = getToken()

  // 使用axios发送POST请求下载模板
  axios({
    method: 'post',
    url: fullUrl,
    data: data,
    responseType: 'blob',
    headers: { 
      'Authorization': 'Bearer ' + token,
      'Content-Type': 'application/json'
    }
  }).then(res => {
    const isBlob = blobValidate(res.data)
    if (isBlob) {
      const blob = new Blob([res.data], { type: res.data.type })
      let downloadFilename = filename || 'template.xlsx'
      // 优先使用服务端返回的文件名
      if (res.headers && res.headers['content-disposition']) {
        const contentDisposition = res.headers['content-disposition']
        const filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/
        const matches = filenameRegex.exec(contentDisposition)
        if (matches != null && matches[1]) {
          downloadFilename = matches[1].replace(/['"]/g, '')
        }
      }
      saveAs(blob, downloadFilename)
    } else {
      printErrMsg(res.data)
    }
  }).catch(error => {
    console.error('下载模板失败:', error)
    Message.error('下载模板失败，请检查网络连接或联系管理员')
  })
}
